package cn.wolfcode.wolf2w.service.impl;


import cn.wolfcode.wolf2w.domain.*;
import cn.wolfcode.wolf2w.query.DestinationQuery;
import cn.wolfcode.wolf2w.repository.DestinationRepository;
import cn.wolfcode.wolf2w.repository.StrategyCatalogRepository;
import cn.wolfcode.wolf2w.repository.StrategyRepository;
import cn.wolfcode.wolf2w.service.IDestinationService;
import cn.wolfcode.wolf2w.service.IRegionService;
import cn.wolfcode.wolf2w.service.IStrategyService;
import cn.wolfcode.wolf2w.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


@Service
//@Transactional mongodb事务
public class DestinationServiceImpl implements IDestinationService{

    @Autowired
    private DestinationRepository destinationRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IRegionService regionService;

    @Autowired
    private StrategyRepository strategyRepository;

    @Autowired
    private IStrategyService strategyService;

    @Autowired
    private StrategyCatalogRepository strategyCatalogRepository;

    @Override
    public void save(Destination destination) {
        destination.setId(null);
        destinationRepository.save(destination);

    }

    @Override
    public void delete(String id) {
        destinationRepository.deleteById(id);
    }

    @Override
    public void update(Destination destination) {
        // 获取用户输入的id
        String desId = destination.getId();
        // 查询对应id在数据库中的数据
        Destination des = mongoTemplate.findById(desId, Destination.class);
        // 将用户输入的简介信息添加到原数据中
        des.setInfo(destination.getInfo());
        destinationRepository.save(des);
    }

    @Override
    public Destination get(String id) {
        // orElse的作用 : 通过findById()方法查询数据库返回值是一个Optional类型,
        // 加上orElse就是如果findById()方法查到有值,返回值.当Optional对象里面的值为空的时候，返回一个默认的值null。
       return destinationRepository.findById(id).orElse(null);

    }

    @Override
    public List<Destination> list() {

        return destinationRepository.findAll();
    }

    @Override
    public Page<Destination> queryForList(DestinationQuery qo) {
              // 创建查询对象
        Query query = new Query();

        // 关键字查询
        if (StringUtils.hasLength(qo.getKeyword())){
            // 对名字进行模糊查询
            query.addCriteria(Criteria.where("name").regex(qo.getKeyword()));
        }
        if (StringUtils.hasLength(qo.getParentId())){
            // 通过目录进行筛选
            query.addCriteria(Criteria.where("parentId").is(qo.getParentId()));
        }else{
            // 如果为null那么就相当于我全部都查
            query.addCriteria(Criteria.where("parentId").is(null));
        }
        // 排序查询
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");

        return DBHelper.query(mongoTemplate,Destination.class,pageable,query);

    }

    @Override
    public List<Destination> queryDesByRegId(String rid) {

        // 通过区域id获取区域对象
        Region region = regionService.get(rid);
        // 获取目的地id集
        List<String> refIds = region.getRefIds();
        // 通过区域id查询目的地集合
        List<Destination> destinations = destinationRepository.findByIdIn(refIds);
        return destinations;
    }

    @Override
    public List<Destination> queryDesByRegIdOnApi(String regionId) {
        List<Destination> list = new ArrayList<>();

        // 国内 id: -1
        if ("-1".equals(regionId)){
            // 通过父级名称中国去查所有省份, 如果使用id后续数据改变会对结果有影响
            list = destinationRepository.findByParentName("中国");
        }else {
            // 查询除国内以外的省份
            list = this.queryDesByRegId(regionId);
        }
        //
        for (Destination destination : list){

            List<Destination> destinations = destinationRepository.findByParentId(destination.getId());
            destination.setChildren(destinations);
        }
        return list;
    }

    @Override
    public List<Destination> queryDesByParentId(String parentId) {
        // 创建一个集合
        List<Destination> list = new ArrayList<>();
        if (!StringUtils.hasLength(parentId)){
            return Collections.emptyList();
        }
        // 获取到createToast()方法中递归的结果
        createToast(list,parentId);
        // 反转
        Collections.reverse(list);
        // 返回集合数据
        return list;
    }

    private void createToast(List<Destination> list, String parentId) {

        // 通过父节点id获取到这个子对象的
        Destination destination = this.get(parentId);

        // 将对象放入集合中
        list.add(destination);

        if (StringUtils.hasLength(destination.getParentId())){
            // 调用自身的方法重新执行操作,直到不满足条件
            createToast(list,destination.getParentId());
        }
    }

    @Override
    public List<Destination> getDestByDeep(int deep) {
        return destinationRepository.findByDeepLessThanEqual(deep);
    }

    @Override
    public List<StrategyCatalog> queryCatalogByDestId(String destId) {
        // 所有指定destId的所有分类攻略
        List<StrategyCatalog> list = strategyCatalogRepository.findByDestId(destId);
        // 遍历分类,查询分类下所有攻略明细
        for(StrategyCatalog strategyCatalog : list){
            // 通过攻略分类id 查询对应攻略明细集合
            List<Strategy> strategys = strategyService.queryCatalogId(strategyCatalog.getId());
            // 将明细加到对应分类上
            strategyCatalog.setStrategies(strategys);
        }
        return list;
    }

    @Override
    public List<Strategy> queryViewunmTop3(String destId) {
        // 创建查询对象
        Query query = new Query();
        // 添加以目的地为条件查询
        query.addCriteria(Criteria.where("destId").is(destId));
        // 分页显示前三条降序点击量数据
        Pageable pageable = PageRequest.of(0, 3, Sort.Direction.DESC, "Viewum");
        // 将条件加入查询对象
        query.with(pageable);
        // 查询条件了条件限制的攻略明细数据
        List<Strategy> list = mongoTemplate.find(query, Strategy.class);
        // 返回数据
        return list;
    }

    @Override
    public List<Travel> queryTravelsToViewingTop3(String destId) {
        // 创建查询对象
        Query query = new Query();
        // 添加以目的地为条件查询
        query.addCriteria(Criteria.where("destId").is(destId));
        // 分页显示前三条降序点击量数据
        Pageable pageable = PageRequest.of(0,3,Sort.Direction.DESC,"Viewum");
        // 将条件加入查询对象
        query.with(pageable);
        List<Travel> travels = mongoTemplate.find(query, Travel.class);
        // 返回数据
        return travels;
    }

    @Override
    public Destination queryByName(String keyword) {
        // 通过关键字查询目的地
        Destination destination = destinationRepository.findByName(keyword);
        return destination;
    }

}
